import * as Cesium from "cesium"
import { defaultStyle } from "./style"
import {
  DrawerBase,
  EventsConfig,
  CesiumEvent,
} from "../Draw/baseDrawers/DrawerBase"
import { BaseMeasure } from "./BaseMeasure"

//Cesium距离测量
export class DistanceMeasure extends BaseMeasure {
  distanceLabels: Cesium.Entity[] = []
  protected events: EventsConfig = {
    cesiumEvents: [
      // 点击拾取
      {
        type: "click",
        callback: (e: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
          const position = this.viewer.scene.pickPosition(e.position)
          if (position) {
            //更新顶点数组
            this.featurePositions.value.push(position)

            //绘制新增线段的距离标注
            if (this.featurePositions.value.length >= 2) {
              const lastPosition =
                this.featurePositions.value[
                  this.featurePositions.value.length - 2
                ]
              const currentPosition =
                this.featurePositions.value[
                  this.featurePositions.value.length - 1
                ]
              this.drawDistanceLabel(lastPosition, currentPosition)
            }
          }
        },
      },
      // 右键结束
      {
        type: "rightclick",
        callback: () => {
          if (this.mousePosition) {
            this.featurePositions.value.push(this.mousePosition)

            //绘制新增线段的距离标注
            if (this.featurePositions.value.length >= 2) {
              const lastPosition =
                this.featurePositions.value[
                  this.featurePositions.value.length - 2
                ]
              const currentPosition =
                this.featurePositions.value[
                  this.featurePositions.value.length - 1
                ]
              this.drawDistanceLabel(lastPosition, currentPosition)
            }
          }
          //绘制
          this.distanceLabels.forEach((item) => this.entities.remove(item))
          this.drawMeasuredEntities()
          this.featurePositions.value = []
          this.end()
        },
      },
    ],
  }
  protected helpers: Cesium.Entity.ConstructorOptions[] = [
    //折线和长度标注
    {
      //label锚点
      position: new Cesium.CallbackPositionProperty(() => {
        const lastPosition =
          this.featurePositions.value[this.featurePositions.value.length - 1]
        if (lastPosition && this.mousePosition) {
          return Cesium.Cartesian3.midpoint(
            lastPosition,
            this.mousePosition,
            new Cesium.Cartesian3(),
          )
        } else {
          return undefined
        }
      }, false),
      label: {
        ...this.styleOption?.label,
        text: new Cesium.CallbackProperty(() => {
          const lastPosition =
            this.featurePositions.value[this.featurePositions.value.length - 1]
          //计算距离
          if (this.mousePosition && lastPosition) {
            return (
              Cesium.Cartesian3.distance(
                this.mousePosition,
                lastPosition,
              ).toFixed(2) + "米"
            )
          } else {
            return ""
          }
        }, false),
      },
      //折线
      polyline: {
        ...this.styleOption?.polyline,
        positions: new Cesium.CallbackProperty(() => {
          if (this.mousePosition && this.featurePositions.value.length > 0) {
            return [...this.featurePositions.value, this.mousePosition]
          } else {
            return undefined
          }
        }, false),
      },
    },
    //鼠标位置点
    {
      position: new Cesium.CallbackPositionProperty(
        () => this.mousePosition,
        false,
      ),
      point: {
        ...this.styleOption?.point,
      },
    },
  ]

  //绘制测定的实体
  protected drawMeasuredEntities() {
    const positions = this.featurePositions.value.map((item) => item.clone())
    this.helperEntities.forEach((entity) => {
      if (entity.polyline) {
        this.drawFeature({
          polyline: {
            positions: new Cesium.CallbackProperty(() => {
              return positions
            }, false),
            depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.ORANGE.withAlpha(0.6),
            }),
          },
        })
      }
    })
    //绘制顶点
    positions.forEach((item, index) => {
      this.drawFeature({
        position: new Cesium.CallbackPositionProperty(() => {
          return positions[index]
        }, false),
        point: {},
      })
    })
    //绘制label
    this.drawPolylineLabel(positions)
    //保存坐标引用——为了支持节点编辑
    this.measuredFeature.push({
      featureId: String(Date.now()),
      positions,
    })
  }

  //绘制距离label
  protected drawDistanceLabel(
    startPoi: Cesium.Cartesian3,
    endPoi: Cesium.Cartesian3,
  ) {
    //计算label定位点——线段中点
    const midPoint = Cesium.Cartesian3.midpoint(
      startPoi,
      endPoi,
      new Cesium.Cartesian3(),
    )

    //计算线段长度
    const distance = Cesium.Cartesian3.distance(startPoi, endPoi).toFixed(2)

    //添加label
    const entity = this.drawFeature({
      position: midPoint,
      label: {
        text: distance + "米",
      },
    })
    this.distanceLabels.push(entity)
  }

  //绘制折线label
  protected drawPolylineLabel(linePositions: Cesium.Cartesian3[]) {
    linePositions.forEach((item, index) => {
      if (index > 0) {
        this.drawFeature({
          position: new Cesium.CallbackPositionProperty(() => {
            return Cesium.Cartesian3.midpoint(
              linePositions[index],
              linePositions[index - 1],
              new Cesium.Cartesian3(),
            )
          }, false),
          label: {
            text: new Cesium.CallbackProperty(() => {
              return (
                Cesium.Cartesian3.distance(
                  linePositions[index],
                  linePositions[index - 1],
                ).toFixed(2) + "米"
              )
            }, false),
          },
        })
      }
    })
  }

  //初始化状态
  protected initStates() {
    this.featurePositions.value = []
    this.distanceLabels.forEach((item) => this.entities.remove(item))
  }
}
